
#include "kb.h"                 // keybaord event type 
#include "touch_algorithm.h"    // touch event type 
#include "custom_event.h"
#include "gui.h"                // GUI header
#include "gui_asset_charmap.h"

#include "views.h"              // include all views 
#include "log.h"                // LOG file 
#define LOG     LOG_INFO0

#include "app_util.h"
#include "fw.h"
#include "em_ble.h"

#include "xapp_ble.h"
#include "xapp_clock.h"
#include "xapp_qrcode.h"
#include "xapp_system.h"

enum tagDeviceInfo
{
    tagDeviceInfoQrcode2Connect,
    tagDeviceInfoReturn,    
    tagQrcodeDevAppTryToEnterFactoryTest,
    tagQrcodeDevAppTryToEnterAdvTypeSel,
};

// declare function 
GUI_VIEW_FUNC_DECLARE_ALL;
static void local_view_event_handler( uint32_t tag );

static uint8_t  string_mac[1+8+8];
static uint8_t string_image_build_datetime[14];
static uint8_t string_charmap_build_datetime[14];
// static uint8_t* mp_qrcode_matrix; 

const static ui_widgets_type_t wglDeviceInfo/*1. modify name*/[] = 
{
    // 背景
    [0] = uiCanvas(0, 0, GUI_LCD_RES_H, GUI_LCD_RES_V, COLOR_BLACK),
    [1] = uiListBox(0, 0, GUI_LCD_RES_H, GUI_LCD_RES_V, 7, 0, 0, false),
    // 产品型号
    [2] = uiLabel(0, 30, GUI_LCD_RES_H, 36, COLOR_ORANGE, COLOR_WHITE, ALIGN_MIDDLE_TOP, FILL_BACKCOLOR, ENCODING_ASCII, FONT_ASCII_1_32_42, "M02", 3),
    // 设备ID
    [3] = uiNumberlistWithBuffer(0, 70, GUI_LCD_RES_H, 32, COLOR_BLACK, COLOR_WHITE, ALIGN_MIDDLE_CENTOR, FILL_NONE, ENCODING_ASCII, FONT_ASCII_1_24_31, "MAC:%08X%04X", string_mac, 1+7+8),
    // 固件版本
    [4] = uiLabel(0, 100, GUI_LCD_RES_H, 32, COLOR_BLACK, COLOR_WHITE, ALIGN_MIDDLE_CENTOR, FILL_NONE, ENCODING_ASCII, FONT_ASCII_1_24_31, FW_REVISION_STRING, FW_REVISION_STRING_LEN),

    [5] = uiLabel(0, 135, GUI_LCD_RES_H, 22, 0x3313, COLOR_WHITE, ALIGN_MIDDLE_CENTOR, FILL_BACKCOLOR, ENCODING_ASCII, FONT_UNICODE_20_29, "PBuild:", 7),
    [6] = uiLabel(0, 190, GUI_LCD_RES_H, 22, 0x3313, COLOR_WHITE, ALIGN_MIDDLE_CENTOR, FILL_BACKCOLOR, ENCODING_ASCII, FONT_UNICODE_20_29, "CBuild:",7),
    // GUI Image version datetime
    [7] = uiTextbox(0, 156, GUI_LCD_RES_H, 26, COLOR_BLACK, COLOR_WHITE, ALIGN_MIDDLE_TOP, FILL_NONE, ENCODING_UTF8, FONT_ASCII_1_22_29),
    // GUI charmap version datetime
    [8] = uiTextbox(0, 210, GUI_LCD_RES_H, 26, COLOR_BLACK, COLOR_WHITE, ALIGN_MIDDLE_TOP, FILL_NONE, ENCODING_UTF8, FONT_ASCII_1_22_29),
};

// const static ui_widgets_type_t wglDeviceInfoTouch[] = 
// {
//     [0] = uiTouch( 70, 130, 100, 100, tagDeviceInfoQrcode2Connect )
// };

static const ui_widgets_type_t uiTouchList[] = 
{
    [0] = uiTouch( 0, 0, GUI_LCD_RES_H/2, SIZE_SCALE(120/*50*/), tagQrcodeDevAppTryToEnterFactoryTest ),
    [1] = uiTouch( GUI_LCD_RES_H/2, 0, GUI_LCD_RES_H/2, SIZE_SCALE(120/*50*/), tagQrcodeDevAppTryToEnterAdvTypeSel ),
};

GUI_VIEW_DEF( viewDevInfo ) = 
{
    // name 
    .name = "App+DeviceInfo",
    
    // init 
    .init = initialize,
    .display_func = display_callback_func,
    .refresh_func_check = display_refresh_func,
    .destroy_func = on_destroy_func,
    .set_parent_func = on_set_parent_func, 
    
    // input 
    .on_touch = on_touch,
    .on_button = on_button,
    .on_event_update = on_event_update,     
    
    .pWidgetlist =  (ui_widgets_type_t*)wglDeviceInfo /* 3. fill with widgets list name */,
    .widget_cnt = WIDGET_COUNT( wglDeviceInfo ), /* 3. fill with widgets list name */

    .flag = GUI_VIEW_FLAG_FUNC
};

static uint32_t timestamp_click ;
static uint8_t enter_factory_test_count;

static uint32_t adv_timestamp_click ;
static uint8_t adv_enter_factory_test_count;

static gui_fling_t* mp_fling;
/* 当前view初始化
// 需要指定前使用的控件组
// 自动更新间隔，不使用自动更新间隔则interval = 0
*/
static void initialize(gui_menu_t * menu, void* pvParameter)
{
    menu->interval = 0;
    menu->lifetime = 0; 

    mp_fling = gui_fling_get();
    gui_fling_init_t init_obj = GUI_FLING_CONFIG(0, 0, GUI_LCD_RES_H, GUI_LCD_RES_V, true, -100, 0, 10, 100, NULL);
    gui_fling_init(mp_fling, &init_obj);
}
static void on_set_parent_func(gui_menu_t * menu, const gui_view_t * parent)
{
    p_this_parent = parent;
}
/* 销毁函数
// 在销毁前处理当前信息，比如不允许销毁时，将当前界面状态保存为background。
// true:  允许销毁
// false: 不允许自动销毁，则GUI只关闭当前显示，输入事件仍由当前view进行处理。
          那么view判断当前状态为background时，作出对应background下的按键、触摸等事件反馈
*/
static uint32_t on_destroy_func(gui_menu_t * menu)
{
    // xapp_qrcode_free_buffer(  );    
    return GUI_DESTROY_RET_DEFAULT; 
}


/* 显示回调
   重新指定参数, 用来获取当前界面的控件组
   ** 当前界面有多个控件组时，应该有条件确定使用哪一组控件组 ** 
*/
static void display_callback_func(gui_menu_t * menu)
{
    ui_property_t prop;
    ui_widgets_type_t * widgets = menu->widgets;
    const xapp_ble_desc_t* p_ble_desc = xapp_ble_get_desc();
    
    if( IS_REQ_SRC_CREATE( menu->source) )
    {
        // 产品型号
        gui_widget_update_prop( &widgets[2], NULL );

        // 设备ID
        const uint8_t* pmac = em_ble_desc.localMAC;
        prop.numberlist.value[1] = uint16_decode(pmac);
        prop.numberlist.value[0] = uint32_decode(pmac+2);
        prop.numberlist.cnt = 2;
        gui_widget_update_prop( &widgets[3], &prop );
        
        // 固件版本 
        gui_widget_update_prop( &widgets[4], NULL );

        PROP_UPDATE_NULL_AT_NO(5);
        PROP_UPDATE_NULL_AT_NO(6);

        // 字库版本
        gui_asset_header_t imageHeader;
        gui_image_assets_get_merge_header(&imageHeader);
        memcpy(string_image_build_datetime, imageHeader.datetime, 14);

        gui_asset_fl_header_t charmapHeader;
        gui_asset_charmap_get_merge_header(&charmapHeader);
        memcpy(string_charmap_build_datetime, charmapHeader.datetime, 14);

        PROP_ASSIGN_TEXT(prop, string_image_build_datetime, 14);
        PROP_UPDATE_AT_NO(7);
        PROP_ASSIGN_TEXT(prop, string_charmap_build_datetime, 14);
        PROP_UPDATE_AT_NO(8);
    }

    if (menu->source == GUI_VIEW_REQ_SRC_UPDATE_FLING)
    {
        PROP_ASSIGN_LISTBOX_OFFSET(prop, mp_fling->roll_offset_total);
        PROP_UPDATE_AT_NO( 1 );
    }
    
    if(p_ble_desc->connected)
        widgets[3].uiNumber.forecolor = COLOR_BLUE;
    else
        widgets[3].uiNumber.forecolor = COLOR_WHITE;
        
}

/* 刷新显示回调
   根据当前状态，重新绘制指定的控件组 
*/
static int display_refresh_func(gui_menu_t * menu)
{
    return 1;
}

static void on_touch(void* pvParameters, gui_menu_t * menu)
{
    tp_algo_evt_t* touch = (tp_algo_evt_t*)pvParameters;

    switch( touch->type )
    {
        case TP_ALGO_EVT_TYPE_HOLD:
        if (touch->deltaY != 0)
        {
            gui_fling_set_roll(mp_fling, touch->deltaY);
        }
        break;

        case TP_ALGO_EVT_TYPE_CLICK:
//        VIEW_CHECK_TOUCH( wglDeviceInfoTouch, touch->x, touch->y, local_view_event_handler);        
        VIEW_CHECK_TOUCH( uiTouchList, touch->x, touch->y, local_view_event_handler  );
        break;        
        
        case TP_ALGO_EVT_TYPE_SLIDE_R:
        local_view_event_handler( tagDeviceInfoReturn );
        break;
        
        default:
        break;
    }
}
/* 界面的按键处理

*/
static void on_button(void* pvParameters, gui_menu_t * menu)
{
    kb_evt_t* kb = (kb_evt_t*)pvParameters;

    switch( kb->type )
    {
        case KB_EVT_CLICK:
        case KB_EVT_SHORT_HOLD_READY:
        local_view_event_handler( tagDeviceInfoReturn ); 
        break;
    }
}

/* 界面的自定义输入事件处理

*/
static void on_event_update(void * pvParameters, gui_menu_t * menu)
{
    custom_evt_t* custom = (custom_evt_t*)pvParameters;
    switch( custom->type )
    {
        case CUSTOM_EVT_TYPE_BLE_CONNECTION_CHANGE:
        gui_update_event();        
        break;
        
        default:
        break;
    }
}

/* 界面的触摸事件
   tag 是生效的控件id, 用户根据生效的tag判断是哪个控件点击了，进行处理
*/
static void local_view_event_handler( uint32_t tag )
{
    switch( tag )
    {
        // case tagDeviceInfoQrcode2Connect:
        // gui_view_create_sub( &viewDevInfo, &viewDevInfo_AppLink );
        // break;

        case tagQrcodeDevAppTryToEnterFactoryTest: 
        {
            uint32_t ticks = em_rtc_get_second_ticks();
            if( ticks > 120 ) // 开机两分钟内才允许进入工厂测试 模式 
            {
                LOG_INFO0("enter factory0 count already timeout 120s" );
                break;
            }

            if( em_rtc_check_time_expired( timestamp_click, EM_RTC_TOTICKS(500) ) )
            {
                enter_factory_test_count = 1;
            }
            else 
            {
                enter_factory_test_count ++;
                
                if( enter_factory_test_count > 5 )
                {
                    xapp_system_set_mode( SYSTEM_MODE_FACTORY_TEST ); // 进入工厂测试模式 
                }
            }
            LOG_INFO1("enter factory0 count = %d", enter_factory_test_count );
            timestamp_click = em_rtc_get_ticks();
        }
        break;
        
        case tagQrcodeDevAppTryToEnterAdvTypeSel: 
        {
            if( em_rtc_check_time_expired( adv_timestamp_click, EM_RTC_TOTICKS(500) ) )
            {
                adv_enter_factory_test_count = 1;
            }
            else 
            {
                adv_enter_factory_test_count ++;
                
                if( adv_enter_factory_test_count > 5 )
                {
                    gui_view_create_sub( &viewDevInfo, &viewAdvTypeSel );
                }
            }
            LOG_INFO1("enter adv_type count = %d", adv_enter_factory_test_count );
            adv_timestamp_click = em_rtc_get_ticks();
        }
        break;
        
        case tagDeviceInfoReturn:
        if( p_this_parent != NULL )
        {
            gui_view_create_return( p_this_parent );
        }
        else 
        {
            gui_view_create_return( &viewAppsList );
        }
        break;
    }

}
